// SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
// SPDX-License-Identifier: Mulan PSL v2
package log

import (
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/sirupsen/logrus"
)

const (
	colorRed  = 31
	colorBlue = 36
	colorGray = 37

	MinLogCaller = 5
	MaxLogCaller = 25

	DefaultTimeFormat = "2006-01-02 15:04:05.000"
)

func getColorByLevel(level logrus.Level) int {
	switch level {
	case logrus.DebugLevel, logrus.WarnLevel:
		return colorBlue
	case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
		return colorRed
	default:
		return colorGray
	}
}

// 类似java logback的格式
type LogbackFormatter struct{}

// 格式如： 2021-01-25 22:42:14.837  INFO 112948 --- [main]    :
func (f *LogbackFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	// output buffer
	output := &bytes.Buffer{}

	// write time
	output.WriteString(entry.Time.Format(DefaultTimeFormat) + " ")

	// write level
	levelColor := getColorByLevel(entry.Level)
	level := strings.ToUpper(entry.Level.String())
	fmt.Fprintf(output, "\x1b[%dm%5s\x1b[0m ", levelColor, level)

	// write process
	pid := os.Getpid()
	pName := filepath.Base(os.Args[0])
	fmt.Fprintf(output, "%d --- [%s] ", pid, pName)

	// 文件信息
	fileVal := "-"
	funcVal := "-"
	for i := MinLogCaller; i < MaxLogCaller; i++ {
		_, file, _, _ := runtime.Caller(i)
		if !strings.Contains(file, "logrus") {
			pc, filePath, lineNo, _ := runtime.Caller(i + 1)
			slashIndex := strings.LastIndex(filePath, "/")
			if slashIndex > 0 {
				fileVal = fmt.Sprintf("%s:%d", filePath[slashIndex+1:], lineNo)
				funcVal = runtime.FuncForPC(pc).Name() + "()"
				break
			}
		}
	}
	output.WriteString(fmt.Sprintf("%s::%s : ", fileVal, funcVal))

	output.WriteString(entry.Message)
	output.WriteByte('\n')

	return output.Bytes(), nil
}
